package com.yangjun.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.JsonParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.databind.JsonMappingException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yangjun.dao.impl.stockAnalysis.StockAnalysisDao;
import com.yangjun.dao.mybatis.mapper.stockAnalysis.BatchDetMapper;
import com.yangjun.dao.mybatis.mapper.stockAnalysis.PSSDetMapper;
import com.yangjun.entity.stockAnalysis.BatchDetEntity;
import com.yangjun.entity.stockAnalysis.PSSDetEntity;
import com.yangjun.entity.stockAnalysis.UnsalableWareEntity;
import com.yangjun.utils.DvDateUtils;
import com.yangjun.utils.JSONUtils;
import com.yangjun.utils.RedisClientLocalUtils;
import com.yangjun.utils.export.ExportExcel;

import jxl.Workbook;
import jxl.write.WritableWorkbook;

/*
 athor:yxw
 purpose: 仓库分析模块的数据读取
 version:V1.0 create on 20161010
 */
@RestController
@RequestMapping("/stockanaysis")
public class StockAnalysisController {
	@Autowired
	StockAnalysisDao saDao;
	@Autowired
	public BatchDetMapper saDaoMy;
	@Autowired
	public PSSDetMapper mydaoPSS;

	private static RedisClientLocalUtils rc = new RedisClientLocalUtils();

	/**
	 * http://192.168.7.32:8080/stockanaysis/main
	 * @param response
	 * @return
	 */
	@RequestMapping("/main")
	@ResponseBody
	public Map<String, Object> main(HttpServletResponse response) {
		response.setHeader("Access-Control-Allow-Origin", "*");

		Map<String, Object> mainData = new HashMap<String, Object>();
		// =================仓库预览
		mainData.put("overview", saDao.getOverView());
		// =================仓库实况.柱状图
		mainData.put(
				"wh_bar",
				getBarData(saDao.getWhStockQty(), "whname", "whname",
						"stockamt", "bingA"));

		// =================商品分类库存.柱状图
		mainData.put(
				"cat_bar",
				getBarData(saDao.getCATStock(), "catname", "catname",
						"stockamt", "仓库分类"));
		// =================仓库实况.饼图
		Map<String, String> mp_bing = new HashMap<String, String>();
		mp_bing.put("whname", "name");
		mp_bing.put("stockamt", "value");
		mainData.put("wh_pie",
				getPaiData(saDao.getWhStockQty(), mp_bing, "仓库实况饼图"));
		// =================仓库趋势.线图
		Map<String, Object> tmp_map = new HashMap<String, Object>();
		// =================滞销
		mainData.put("dull_line", main_dull());
		// =================进销存

		mainData.put(
				"pss_line_inqty",
				getBarData(saDao.getPSS(), "data_date", "data_date", "inqty",
						"入库数量"));
		mainData.put(
				"pss_line_inamt",
				getBarData(saDao.getPSS(), "data_date", "data_date", "inamt",
						"入库金额"));
		mainData.put(
				"pss_line_outqty",
				getBarData(saDao.getPSS(), "data_date", "data_date", "outqty",
						"出库数量"));
		mainData.put(
				"pss_line_outamt",
				getBarData(saDao.getPSS(), "data_date", "data_date", "outamt",
						"出库金额"));
		mainData.put(
				"pss_line_stockqty",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"stockqty", "库存数量"));
		mainData.put(
				"pss_line_stockamt",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"stockamount", "库存金额"));

		mainData.put(
				"pss_line_salesrecount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"salesrecount", "销售退货入库"));
		mainData.put(
				"pss_line_salesreamount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"salesreamount", "销售退货入库"));

		mainData.put(
				"pss_line_purincount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"purincount", "采购入库"));
		mainData.put(
				"pss_line_purinamount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"purinamount", "采购入库"));

		mainData.put(
				"pss_line_alloincount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"alloincount", "调拨入库"));
		mainData.put(
				"pss_line_alloinamount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"alloinamount", "调拨入库"));

		mainData.put(
				"pss_line_wholesalerecount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"wholesalerecount", "批发退货入库"));
		mainData.put(
				"pss_line_wholesalereamount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"wholesalereamount", "批发退货入库"));

		mainData.put(
				"pss_line_salescount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"salescount", "销售出库"));
		mainData.put(
				"pss_line_salesamount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"salesamount", "销售出库"));

		mainData.put(
				"pss_line_purrecount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"purrecount", "采购退货出库"));
		mainData.put(
				"pss_line_purreamount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"purreamount", "采购退货出库"));

		mainData.put(
				"pss_line_allooutcount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"allooutcount", "调拨出库"));
		mainData.put(
				"pss_line_allooutamount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"allooutamount", "调拨出库"));

		mainData.put(
				"pss_line_wholesalecount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"wholesalecount", "批发出库"));
		mainData.put(
				"pss_line_wholesaleamount",
				getBarData(saDao.getPSS(), "data_date", "data_date",
						"wholesaleamount", "批发出库"));

		// =================批次.线图
		tmp_map.put(
				"skuqty",
				getBarData(saDao.getBatch(), "batchtype", "orderno", "skuqty",
						"skuqty"));
		mainData.put("batch_line", tmp_map);
		// =================批次.饼图
		Map<String, String> batch_bing = new HashMap<String, String>();
		batch_bing.put("batchtype", "name");
		batch_bing.put("skuqty", "value");
		// =================维度信息.店铺列表
		mainData.put("batch_pie",
				getPaiData(saDao.getBatch(), batch_bing, "批次饼图"));
		mainData.put("allocate_shoplist", saDao.getShop());
		// =================维度信息.仓库列表
		List<String> lstWh = new ArrayList<String>();
		lstWh.add("whcode");
		lstWh.add("whname");
		mainData.put("whlist", getCustColums(saDao.getWhStockQty(), lstWh));


		mainData.put("catlist", saDao.getCATList());
		return mainData;
	}

	// 获取仓库趋势数据
	@RequestMapping("/whdata")
	@ResponseBody
	public Map<String, Object> whdata(HttpServletResponse resp,
			HttpServletRequest req,
			@RequestParam(value = "whcode", required = true) String whcode) {
		Map<String, Object> mainData = new HashMap<String, Object>();
		resp.setHeader("Access-Control-Allow-Origin", "*");
		mainData.put("wh_line", main_whstockdate(whcode));
		return mainData;
	}
	
	
	
	// 获取财务分类趋势数据
	@RequestMapping("/catdata")
	@ResponseBody
	public Map<String, Object> catdata(HttpServletResponse resp,
			HttpServletRequest req,
			@RequestParam(value = "catname", required = true) String catname) {
		Map<String, Object> mainData = new HashMap<String, Object>();
		resp.setHeader("Access-Control-Allow-Origin", "*");
		
		Map<String, Object> tmp_map = new HashMap<String, Object>();
		tmp_map.put(
				"skuqty",
				getBarData(saDao.getCATStock(catname), "data_date",
						"data_date", "skuqty", "SKU数"));
		tmp_map.put(
				"batchqty",
				getBarData(saDao.getCATStock(catname),
						"data_date", "data_date", "batchqty", "批号数"));

		tmp_map.put(
				"stockamt",
				getBarData(saDao.getCATStock(catname),
						"data_date", "data_date", "stockamt", "库存金额"));

		tmp_map.put(
				"stockqty",
				getBarData(saDao.getCATStock(catname),
						"data_date", "data_date", "stockqty", "库存数量"));
		tmp_map.put(
				"turnover_days",
				getBarData(saDao.getCATStock(catname),
						"data_date", "data_date", "turnover_days", "周转天数"));
		// mainData.put("whstockqtyhis_zhe", tmp_map);
		
		mainData.put("cat_line", tmp_map);
		return mainData;
	}
	


	// 获取调拨数据
	@RequestMapping("/allocate")
	@ResponseBody
	public Map<String, Object> allocate(HttpServletResponse resp,
			HttpServletRequest req,
			@RequestParam(value = "shopcode", required = false) String shopcode) {
		Map<String, Object> mainData = new HashMap<String, Object>();
		resp.setHeader("Access-Control-Allow-Origin", "*");
		mainData.put("allocate_lie", main_allocate(shopcode));

		return mainData;
	}

	// 获取批次数据
	@RequestMapping("/batch")
	@ResponseBody
	public Map<String, Object> batch(HttpServletResponse resp,
			HttpServletRequest req,
			@RequestParam(value = "batch", required = false) String batch) {
		Map<String, Object> mainData = new HashMap<String, Object>();
		resp.setHeader("Access-Control-Allow-Origin", "*");
		mainData.put("allocate_lie", main_allocate(batch));
		// 滞销不分仓
		return mainData;
	}

	public Map<String, Object> main_whstockdate(String whcode) {

		// 总库存折线默认存储仓
		Map<String, Object> tmp_map = new HashMap<String, Object>();
		tmp_map.put(
				"skuqty",
				getBarData(saDao.getWhStockHis(whcode, "skuqty"), "data_date",
						"data_date", "skuqty", "SKU数"));
		tmp_map.put(
				"batchqty",
				getBarData(saDao.getWhStockHis(whcode, "batchqty"),
						"data_date", "data_date", "batchqty", "批号数"));

		tmp_map.put(
				"stockamt",
				getBarData(saDao.getWhStockHis(whcode, "stockamt"),
						"data_date", "data_date", "stockamt", "库存金额"));

		tmp_map.put(
				"stockqty",
				getBarData(saDao.getWhStockHis(whcode, "stockqty"),
						"data_date", "data_date", "stockqty", "库存数量"));
		tmp_map.put(
				"turnover_days",
				getBarData(saDao.getWhStockHis(whcode, "turnover_days"),
						"data_date", "data_date", "turnover_days", "周转天数"));
		// mainData.put("whstockqtyhis_zhe", tmp_map);

		return tmp_map;
	}

	public Map<String, Object> main_inventory() {
		Map<String, Object> tmp_map = new HashMap<String, Object>();
		tmp_map = new HashMap<String, Object>();
		tmp_map.put(
				"pandian_zhe_overageamount",
				getBarData(saDao.getInventory("-1", "overageamount"),
						"data_date", "data_date", "overageamount",
						"overageamount"));

		tmp_map.put(
				"pandian_zhe_shortageamount",
				getBarData(saDao.getInventory("-1", "shortageamount"),
						"data_date", "data_date", "shortageamount",
						"shortageamount"));
		return tmp_map;
	}

	public Map<String, Object> main_dull() {

		Map<String, Object> tmp_map = new HashMap<String, Object>();
		// 滞销默认值
		// tmp_map = new HashMap<String, Object>();
		tmp_map.put(
				"skuqty",
				getBarData(saDao.getDullSale("-1", "skuqty"), "data_date",
						"data_date", "skuqty", "SKU数"));
		tmp_map.put(
				"batchqty",
				getBarData(saDao.getDullSale("-1", "batchqty"), "data_date",
						"data_date", "batchqty", "批号数"));

		tmp_map.put(
				"stockamt",
				getBarData(saDao.getDullSale("-1", "stockamt"), "data_date",
						"data_date", "stockamt", "库存金额"));

		tmp_map.put(
				"stockqty",
				getBarData(saDao.getDullSale("-1", "stockqty"), "data_date",
						"data_date", "stockqty", "库存数量"));

		// mainData.put("zhixiao_zhe", tmp_map);
		return tmp_map;
	}

	public Map<String, Object> main_allocate(String shopcode) {

		// 总库存折线默认存储仓
		Map<String, Object> tmp_map = new HashMap<String, Object>();
		tmp_map = new HashMap<String, Object>();
		tmp_map.put(
				"qty",
				getBarData2(saDao.getAllocate(shopcode), "data_date",
						"data_date", "allocoutqty", "allocinqty", "数量"));
		tmp_map.put(
				"amt",
				getBarData2(saDao.getAllocate(shopcode), "data_date",
						"data_date", "allocoutamt", "allocinamt", "金额"));
		tmp_map.put(
				"batch",
				getBarData2(saDao.getAllocate(shopcode), "data_date",
						"data_date", "batchoutqty", "batchinqty", "批号数"));
		tmp_map.put(
				"sku",
				getBarData2(saDao.getAllocate(shopcode), "data_date",
						"data_date", "skuoutqty", "skuinqty", "SKU数"));

		return tmp_map;
	}

	//

	public Map<String, Object> getPaiData(List<Map<String, Object>> oriData,
			Map<String, String> keys, String name) {
		Map<String, Object> rtl = new HashMap<String, Object>();

		List<Map<String, Object>> item_data = new ArrayList<Map<String, Object>>();
		List<Object> legend_row = new ArrayList<Object>();
		// xAxis,legend,today,name
		for (Map<String, Object> item : oriData) {
			Map<String, Object> item_data_row = new HashMap<String, Object>();
			for (Map.Entry entity : keys.entrySet()) {
				String key = entity.getKey().toString();
				String value = entity.getValue().toString();
				item_data_row.put(value, item.get(key));
				if (entity.getValue().toString() == "name") {
					legend_row.add(item.get(key));
				}
			}
			item_data.add(item_data_row);
		}
		rtl.put("legend", legend_row);
		rtl.put("data", item_data);
		rtl.put("name", name);
		return rtl;
	}

	public Map<String, Object> getBarData(List<Map<String, Object>> oriData,
			String xAxis, String legend, String today, String name) {
		Map<String, Object> rtl = new HashMap<String, Object>();
		List<Object> xaxis_row = new ArrayList<Object>();
		List<Object> legend_row = new ArrayList<Object>();
		List<Object> today_row = new ArrayList<Object>();
		// xAxis,legend,today,name
		for (Map<String, Object> item : oriData) {
			xaxis_row.add(item.get(xAxis));
			legend_row.add(item.get(legend));
			today_row.add(item.get(today));
		}
		rtl.put("xAxis", xaxis_row);
		rtl.put("legend", legend_row);
		rtl.put("data", today_row);
		rtl.put("name", name);

		return rtl;
	}

	public Map<String, Object> getBarData2(List<Map<String, Object>> oriData,
			String xAxis, String legend, String data, String data2, String name) {
		Map<String, Object> rtl = new HashMap<String, Object>();
		List<Object> xaxis_row = new ArrayList<Object>();
		List<Object> legend_row = new ArrayList<Object>();
		List<Object> data_row = new ArrayList<Object>();
		List<Object> data_row2 = new ArrayList<Object>();
		// xAxis,legend,today,name
		for (Map<String, Object> item : oriData) {
			xaxis_row.add(item.get(xAxis));
			legend_row.add(item.get(legend));
			data_row.add(item.get(data));
			data_row2.add(item.get(data2));
		}
		rtl.put("xAxis", xaxis_row);
		rtl.put("legend", legend_row);
		rtl.put("data", data_row);
		rtl.put("data2", data_row2);
		rtl.put("name", name);

		return rtl;
	}

	public Map<String, Object> getBarData3(List<Map<String, Object>> oriData,
			String xAxis, String legend, String data, String data2,
			String data3, String name) {
		Map<String, Object> rtl = new HashMap<String, Object>();
		List<Object> xaxis_row = new ArrayList<Object>();
		List<Object> legend_row = new ArrayList<Object>();
		List<Object> data_row = new ArrayList<Object>();
		List<Object> data_row2 = new ArrayList<Object>();
		List<Object> data_row3 = new ArrayList<Object>();
		// xAxis,legend,today,name
		for (Map<String, Object> item : oriData) {
			xaxis_row.add(item.get(xAxis));
			legend_row.add(item.get(legend));
			data_row.add(item.get(data));
			data_row2.add(item.get(data2));
			data_row3.add(item.get(data3));
		}
		rtl.put("xAxis", xaxis_row);
		rtl.put("legend", legend_row);
		rtl.put("data", data_row);
		rtl.put("data2", data_row2);
		rtl.put("data3", data_row3);
		rtl.put("name", name);

		return rtl;
	}

	// 工具函数-取集合中指定的列集
	public List<Map<String, Object>> getCustColums(
			List<Map<String, Object>> oriData, List<String> keys) {
		List<Map<String, Object>> lstReturn = new ArrayList<Map<String, Object>>();
		for (Map<String, Object> item : oriData) {
			Map<String, Object> mp = new HashMap<String, Object>();
			for (String item_key : keys) {
				mp.put(item_key, item.get(item_key));
			}
			lstReturn.add(mp);
		}
		return lstReturn;
	}

	/**
	 * http://192.168.7.32:8080/stockanaysis/batchdet?bathtype=1&pageNum=0&pageSize=10
	 * @param resp
	 * @param req
	 * @param bathtype
	 * @param pageNum
	 * @param pageSize
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping("/batchdet")
	@ResponseBody
	public PageInfo<BatchDetEntity> getBatchDet(
			HttpServletResponse resp,
			HttpServletRequest req,
			@RequestParam(value = "bathtype", required = false) String bathtype,
			@RequestParam(value = "pageNum", required = false) String pageNum,
			@RequestParam(value = "pageSize", required = false) String pageSize) {
		PageInfo<BatchDetEntity> resultMap = null;
		if ("0".equals(pageNum) && "1".equals(bathtype)) {
			try {
				String value = rc.getValue("BatchDet_batchtype_default_1");
				System.out.println("value=="+value);
				resultMap= JSONUtils.strToObj(value, PageInfo.class);
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (resultMap == null || resultMap.getSize() < 1) {
			Map<String, String> parms = new HashMap<String, String>();
			parms.put("batchtype", bathtype);
			PageHelper.startPage(Integer.parseInt(pageNum),
					Integer.parseInt(pageSize), true, true, true);
			resultMap = new PageInfo<BatchDetEntity>(saDaoMy.select(parms));
		}

		return resultMap;
	}

	// 进销存明细
	@RequestMapping("/pssdet")
	@ResponseBody
	public PageInfo<PSSDetEntity> getBatchDet(HttpServletResponse resp,
			HttpServletRequest req,
			@RequestParam(value = "pageNum", required = false) String pageNum,
			@RequestParam(value = "pageSize", required = false) String pageSize) {

		PageHelper.startPage(Integer.parseInt(pageNum),
				Integer.parseInt(pageSize), true, true, true);
		PageInfo<PSSDetEntity> page = new PageInfo<PSSDetEntity>(
				mydaoPSS.select());

		return page;
	}
	
	/**
	 * http://192.168.7.32:8080/stockanaysis/exportExcel?name=unsalable/batchdet
	 * @param response
	 */
	@RequestMapping("/exportExcel")
    public void exportMatchWare(HttpServletResponse response,
    	@RequestParam(value = "name", required = true) String name){//unsalable/batchdet
    	response.setCharacterEncoding("UTF-8");
    	response.setContentType("octets/stream");
    	String formatDate = DvDateUtils.format(new Date(), "yyyyMMddHHmmss");
        OutputStream out=null;
        WritableWorkbook workbook;
		try {
			String codedFileName = "";
			if("unsalable".equals(name.trim())){
				codedFileName = java.net.URLEncoder.encode("滞销明细","UTF-8")+"_"+formatDate;
			}else if ("batchdet".equals(name.trim())){
				codedFileName = java.net.URLEncoder.encode("批次明细","UTF-8")+"_"+formatDate;
			}
			response.addHeader("Content-Disposition", "attachment;filename="+codedFileName+".xls");
			out = response.getOutputStream();
			workbook = Workbook.createWorkbook(out);
			if("unsalable".equals(name.trim())){
				List<UnsalableWareEntity> unsalableWareList = saDaoMy.unsalableWare();
				String[] titles={"商品编码","商品名称","最后采购时间","库存金额","库存数量","近30天出库量","周转天数","入库天数","滞销级别"};
				String[] fields={"warecode","warename","lastpurtime","stockamt","stockqty","salescount30","turnoverday","purdaycnt","unlevel"};
				ExportExcel<UnsalableWareEntity> export = new ExportExcel<UnsalableWareEntity>();
				export.fillExcel(workbook, UnsalableWareEntity.class,
						titles, fields,
						"滞销明细数据", unsalableWareList);
			}else if ("batchdet".equals(name.trim())){
				List<BatchDetEntity> exportBatchDetList = saDaoMy.exportBatchDet();
				String[] titles={"批号数","商品编码","商品名称","批号","库存"};
				String[] fields={"batchtype","warecode","warename","batchno","stockqty"};
				ExportExcel<BatchDetEntity> export = new ExportExcel<BatchDetEntity>();
				export.fillExcel(workbook, BatchDetEntity.class,
						titles, fields,
						"批次明细数据", exportBatchDetList);
			}
			workbook.write();
			workbook.close();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
    	
    }

}
